home *** CD-ROM | disk | FTP | other *** search
- /* ASCII Transfer External for Hermes © 1990 By John Raymonds.
-
- Written in THINK C 4.0.1 as an example external for Hermes protocol
- developers. Use of any code shown below in any program other than
- an external to be used with Hermes requires written permission from
- the author:
-
- John Raymonds
- 76174,205 (Compuserve)
- D3885 (AppleLink)
-
- Comments and suggestions are welcome.
-
- */
-
- #include "Protocol.h"
- #include "ASCII.h"
-
- extern ProtoRecPtr PRP;
- extern ProtoGloPtr PGP;
-
- OsErr SendASCII()
- {
- OsErr err;
- register ProtoRecPtr prp;
- register ProtoGloPtr pgp;
- int i, c, errCount, conErr, Done;
- pgp = PGP;
- prp = PRP;
- err = noErr;
- conErr = 0;
- if (prp->F.B.transMode != TERMINALMODE) {
- SendString(0L);
- SendString("\pASCII 1.0d6 - Type Control-K to abort,");
- SendString("\pControl-P to pause, and (SPACE) to continue.");
- SendString(0L);
- FlushWrite();
- }
- Done = FALSE;
- while (!Done) {
- errCount = pgp->errCount;
- if (!pgp->DIOP.ioRefNum) {
- if (prp->filesDone < prp->fileCount) {
- /* reset the time and count */
- prp->startTime = TickCount();
- prp->bytesDone = 0;
- /* get the file name */
- Pstrcpy(pgp->fName, *prp->fList[prp->filesDone].fName);
- /* get the file info */
- pgp->FP.ioCompletion = 0L;
- pgp->FP.ioNamePtr = pgp->fName;
- pgp->FP.ioVRefNum = prp->fList[prp->filesDone].vRefNum;
- pgp->FP.ioFVersNum = 0;
- pgp->FP.ioFDirIndex = 0;
- err = PBGetFInfo(&pgp->FP, FALSE);
- if (!err) {
- /* set the byte count */
- prp->bytesTotal = pgp->FP.ioFlLgLen;
- if (pgp->FP.ioFlFndrInfo.fdType != 'TEXT') {
- SendString(0L);
- SendString("\pThat's not a 'TEXT' file!");
- pgp->errFatal = NOTTEXT;
- prp->F.B.stopTrans = TRUE;
- }
- else {
- /* open the data fork: REMEMBER TO USE READ-ONLY
- PERMISSION SO OTHERS CAN PLAY WITH THE FILE!
- */
- pgp->DIOP.ioCompletion = 0L;
- pgp->DIOP.ioNamePtr = pgp->fName;
- pgp->DIOP.ioVRefNum = prp->fList[prp->filesDone].vRefNum;
- pgp->DIOP.ioVersNum = 0;
- pgp->DIOP.ioPermssn = fsRdPerm;
- pgp->DIOP.ioMisc = 0L;
- err = PBOpen(&pgp->DIOP, FALSE);
- }
- }
- }
- else {
- Done = TRUE;
- }
- }
- else {
- /* send out a word wrapped line of text */
- Pstrcpy(pgp->lineBuffer, pgp->lineExtra);
- pgp->lineExtra[0] = 0;
- for (;;) {
- c = readAByte();
- if ((c == '\r') && (pgp->lastC == '\n')) {
- c = readAByte();
- }
- else if ((c == '\n') && (pgp->lastC == '\r')) {
- c = readAByte();
- }
- pgp->lastC = c;
- if (c == '\n') {
- c = '\r';
- }
- if (c == '\r') {
- /* just write out the line */
- SendString(pgp->lineBuffer);
- break;
- }
- if (c == '\t') {
- /* convert tabs to spaces (tab length of 4) */
- c = 3-(pgp->lineBuffer[0] & 0x03);
- for (i = 0; i<c; i++) {
- Pstrcad(pgp->lineBuffer, ' ');
- if (pgp->lineBuffer[0] == LINESIZE-1) {
- break;
- }
- }
- c = ' ';
- }
- if (c >= 0) {
- Pstrcad(pgp->lineBuffer, (char) c);
- if (pgp->lineBuffer[0] == LINESIZE) {
- /* do a word wrap */
- for (i = LINESIZE+1; i>0; i--) {
- if (pgp->lineBuffer[i] == ' ') {
- break;
- }
- }
- if (i) {
- /* break at the space */
- pgp->lineBuffer[0] = i-1;
- pgp->lineBuffer[i] = LINESIZE-i;
- Pstrcpy(pgp->lineExtra, &pgp->lineBuffer[i]);
- }
- /* send out what we have */
- SendString(pgp->lineBuffer);
- break;
- }
- }
- if (c == eofErr) {
- /* write out the line and finish */
- SendString(pgp->lineBuffer);
- /* finished with this file */
- prp->F.B.newFile = TRUE;
- /* return to Hermes for update */
- Return(0, &pgp->SSR);
- /* bump up the file count AFTER we come back from Hermes */
- ++prp->filesDone;
- /* close the file */
- PBClose(&pgp->DIOP, FALSE);
- PBFlushVol(&pgp->DIOP, FALSE);
- pgp->DIOP.ioRefNum = 0;
- c = noErr;
- break;
- }
- }
- FlushWrite();
- if (c < 0) {
- err = c;
- }
- if (!err) {
- /* check for a pause */
- c = WaitForChar(0);
- if (PAUSE(c)) {
- /* wait for a continue */
- do {
- c = WaitForChar(60);
- if (c == TIMEOUT) {
- /* stop transfer if nothing comes in for a minute */
- pgp->errFatal = NOCONTINUE;
- Done = TRUE;
- break;
- }
- } while(!CONTINUE(c));
- }
- if (c == ABORT) {
- PRP->F.B.stopTrans = TRUE;
- Done = TRUE;
- }
- }
- }
- if (errCount != pgp->errCount) {
- conErr++;
- if (conErr >= MAXERR) {
- pgp->errFatal = TOOMANYERR;
- }
- }
- else {
- conErr = 0;
- }
- if (err || prp->F.B.carrierLost) {
- Done = TRUE;
- }
- if (prp->F.B.stopTrans || (conErr >= MAXERR)) {
- Done = TRUE;
- }
- }
- /* see if the file is still open */
- if (pgp->DIOP.ioRefNum) {
- PBClose(&pgp->DIOP, FALSE);
- PBFlushVol(&pgp->DIOP, FALSE);
- }
- /* flush any characters still coming in */
- FlushModemInput();
- if (prp->F.B.transMode != TERMINALMODE) {
- SendString(0L);
- SendString(0L);
- SendString("\pASCII Send Finished...");
- }
- FlushWrite();
- /* we are reserving err for Mac OS errors only...
-
- errFatal is keeping track of any protocol erorrs that may
- make the transfer fail.
- */
- if (!err) {
- if (pgp->errFatal) {
- SetError(pgp->errFatal);
- }
- }
- else {
- SetError(err);
- }
- /* MAKE SURE WE RETURN WITH A NON-ZERO ERROR CODE!!! */
- if (!err) {
- err = 128;
- }
- return(err);
- }
-
- int readAByte()
- {
- register OsErr err;
- register ProtoGloPtr pgp;
- pgp = PGP;
- if (pgp->rBValid) {
- --pgp->rBValid;
- return((int) pgp->theData[pgp->rBPos++]);
- }
- else {
- /* read some data into the buffer */
- pgp->DIOP.ioBuffer = (Ptr) &pgp->theData[0];
- pgp->DIOP.ioReqCount = 1024;
- pgp->DIOP.ioPosMode = fsFromMark;
- pgp->DIOP.ioPosOffset = 0;
- err = PBRead(&pgp->DIOP, FALSE);
- if (pgp->DIOP.ioActCount) {
- PRP->bytesDone += pgp->DIOP.ioActCount;
- err = noErr;
- }
- if (err) {
- return(err);
- }
- pgp->rBValid = pgp->DIOP.ioActCount;
- pgp->rBPos = 0;
- return(readAByte());
- }
- }
-